package com.leyou.item.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.PageResult;
import com.leyou.item.dto.CartDto;
import com.leyou.item.mapper.*;
import com.leyou.item.pojo.*;
import com.leyou.item.service.CategoryService;
import com.leyou.item.service.GoodsService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;


    @Override
    public PageResult<SpuBo> querySpuByPageAndSort(Integer page, Integer rows, Boolean saleable, String key) {
        // 1、查询SPU
        // 分页,最多允许查100条
        PageHelper.startPage(page,Math.min(rows,100));
        // 创建查询条件
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        // 是否过滤上下架
        if(saleable!=null){
            criteria.orEqualTo("saleable", saleable);
        }
        //是否模糊查询
        if(StringUtils.isNotBlank(key)){
            criteria.andLike("title","%"+key+"%");
        }
        Page<Spu> pageInfo = (Page<Spu>) this.spuMapper.selectByExample(example);
        List<SpuBo> list =pageInfo.getResult().stream().map(spu -> {
            //2把spu变成spuBo
            SpuBo spuBo = new SpuBo();
            //属性拷贝
            BeanUtils.copyProperties(spu,spuBo);
            //3. 查询spu的商品分类名称，要查三级分类
            List<String>  names=  this.categoryService.queryNameByIds(Arrays.asList(spu.getCid1(),spu.getCid2(),spu.getCid3()));
            //讲分类名称拼接后存入
            spuBo.setCname(StringUtils.join(names,"/"));
            //4查询spu 的品牌名称
            Brand brand = this.brandMapper.selectByPrimaryKey(spu.getBrandId());
            spuBo.setBname(brand.getName());
            return spuBo;
        }).collect(Collectors.toList());
        return  new PageResult<>(pageInfo.getTotal(),list);
    }


    /**
     * @author:zty
     * @date: 2019年01月18日 11:37:35
     * @description
     * @method  querySpuDetailById
     * @param id
     * @return com.leyou.item.pojo.SpuDetail
     */
    @Override
    public SpuDetail querySpuDetailById(Long id) {
        SpuDetail spuDetail = this.spuDetailMapper.selectByPrimaryKey(id);
        if (spuDetail == null) {
            throw new LyException(ExceptionEnum.SPU_NOT_FOUND);
        }
        return spuDetail;

    }


    /**
     * @author:zty
     * @date: 2019年01月18日 09:22:17
     * @description 通过spuId查询skus
     * @method  querySkuBySpuId
     * @param spuId
     * @return java.util.List<com.leyou.item.pojo.Sku>
     */
    @Override
    public List<Sku> querySkuBySpuId(Long spuId) {
        //查询SKU
        Sku record = new Sku();
        record.setSpuId(spuId);
        List<Sku> skus = this.skuMapper.select(record);
        for (Sku sku : skus) {
            //同时查询出库存
            Integer stock = this.stockMapper.selectByPrimaryKey(sku.getId()).getStock();
            sku.setStock(stock);
        }
        return  skus;
    }
    @Override
    public Spu querySpuBySpuId(Long spuId) {
        //根据spuId查询spu
        Spu spu = spuMapper.selectByPrimaryKey(spuId);

        //查询spuDetail
        SpuDetail detail = querySpuDetailById(spuId);

        //查询skus
        List<Sku> skus = querySkuBySpuId(spuId);

        spu.setSpuDetail(detail);
        spu.setSkus(skus);

        return spu;

    }

    @Override
    public List<Sku> querySkuByIds(List<Long> ids) {
        List<Sku> skus = skuMapper.selectByIdList(ids);
        if (CollectionUtils.isEmpty(skus)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        //填充库存
        fillStock(ids, skus);
        return skus;
    }

    private void fillStock(List<Long> ids, List<Sku> skus) {
        //批量查询库存
        List<Stock> stocks = stockMapper.selectByIdList(ids);
        if (CollectionUtils.isEmpty(stocks)) {
            throw new LyException(ExceptionEnum.STOCK_ERROR);
        }
        //首先将库存转换为map，key为sku的ID
        Map<Long, Integer> map = stocks.stream().collect(Collectors.toMap(s -> s.getSkuId(), s -> s.getStock()));

        //遍历skus，并填充库存
        for (Sku sku : skus) {
            sku.setStock(map.get(sku.getId()));
        }
    }
    /**
     * @author:zty
     * @date: 2019年01月18日 11:00:30
     * @description 修改商品
     * @method  update
     * @param spu
     * @return void
     */
    @Transactional
    @Override
    public void update(SpuBo spu) {
        //判断商品id是否为空
        if (null==spu.getId()){
            throw new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);
        }
        //因为sku,stock都属于不固定的信息，所有没办法直接修改，,只能把原来数据删除,然后把新数据添加进去
        //查询原来的sku
        Sku s = new Sku();
        s.setSpuId(spu.getId());
        List<Sku> skuList = skuMapper.select(s);
        if (!CollectionUtils.isEmpty(skuList)){
            //删除之前的sku
            int count = skuMapper.delete(s);
            if (count != skuList.size()){
                throw  new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);
            }
            List<Long> ids = skuList.stream().map(Sku::getId).collect(Collectors.toList());
            count = stockMapper.deleteByIdList(ids);
            if (count!= skuList.size()){
                throw  new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);
            }
            //修改spu
            //以下几个字段不修改(设置为null之后,使用通用mapper的updateSelective方法默认不更新)
            spu.setValid(null);
            spu.setSaleable(null);
            spu.setCreateTime(null);
            spu.setLastUpdateTime(new Date());
            count = spuMapper.updateByPrimaryKeySelective(spu);
            if(count!=1){
                throw new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);
            }
            //新增sku和stock
            saveSkuAndStock(spu);
        }

    }


    @Override
    public void deleteGoods(Long spuId) {
         this.spuMapper.deleteByPrimaryKey(spuId);
    }

    @Override
    public void onSaleGoods(Long spuId) {

    }

    @Override
    public void offSaleGoods(Long spuId) {

    }

    /**
     * 减库存
     *
     * @param cartDtos
     */
    @Transactional
    @Override
    public void decreaseStock(List<CartDto> cartDtos) {
        for (CartDto cartDto : cartDtos) {
        int count =  stockMapper.decreaseStock(cartDto.getSkuId(),cartDto.getNum());
            if (count != 1){
                throw new LyException(ExceptionEnum.STOCK_ERROR);
            }
        }

    }
    /**
     * 订单支付超时,取消订单后把减掉的库存加回来
     *
     * @param map
     */
    @Override
    public void creaseStock(Map<Long, Integer> map) {
        Set<Long> longs = map.keySet();
        for (Long skuId : longs) {
            Integer num = map.get(skuId);
            int count = stockMapper.creaseStock(skuId, num);
            if (count !=1){
                throw  new LyException(ExceptionEnum.STOCK_ERROR);
            }
        }
    }


    @Override
    public Sku querySkuBySkuId(Long id) {
        return skuMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<Sku> queryAllSpuId() {
        return skuMapper.selectAll();
    }
    @Override
    public void save(Spu spu) {
        // 保存spu
        spu.setSaleable(true);
        spu.setValid(true);
        spu.setCreateTime(new Date());
        spu.setLastUpdateTime(spu.getCreateTime());
        int count = this.spuMapper.insert(spu);
        if (count != 1) {
            throw new LyException(ExceptionEnum.GOODS_INSERT_ERROR);
        }

        //新增spu_details
        SpuDetail detail = spu.getSpuDetail();
        detail.setSpuId(spu.getId());
        count = spuDetailMapper.insertSelective(detail);
        if (count != 1) {
            throw new LyException(ExceptionEnum.GOODS_INSERT_ERROR);
        }
        //新增sku和stock
        saveSkuAndStock(spu);//调用下面定义好的方法

    }

    private void saveSkuAndStock(Spu spu) {
        //新增
        int count;
        List<Sku> skuList = spu.getSkus();
        ArrayList<Stock> stocklist = new ArrayList<>();
        for (Sku sku : skuList) {
            if (!sku.getEnable()) {
                continue;
            }
            // 保存sku
            sku.setSpuId(spu.getId());
            // 默认不参与任何促销
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            count = this.skuMapper.insert(sku);
            System.out.println(sku);
            if(count !=1){
                throw  new LyException(ExceptionEnum.GOODS_INSERT_ERROR);
            }
            // 保存库存信息
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            this.stockMapper.insert(stock);
        }
    }
}
